package ru.nstu.isma.core.lang.ast.visitor;

import ru.nstu.isma.core.lang.ast.LismaBaseVisitor;
import ru.nstu.isma.core.lang.ast.LismaParser;
import ru.nstu.isma.core.hsm.*;
import ru.nstu.isma.core.hsm.pde.HMApproximateVariable;
import org.antlr.v4.runtime.misc.NotNull;

/**
 * by Alexey Bessonov
 * Date: 28.11.13
 * Time: 23:32
 */
public class VariableTableAggregatorVisitor extends LismaBaseVisitor {

    protected HMVariableTable table;

    private HMStateAutomata automata;

    public VariableTableAggregatorVisitor(HMVariableTable table, HMStateAutomata automata) {
        this.table = table;
        this.automata = automata;
    }

    @Override
    public Object visitConstant(@NotNull LismaParser.ConstantContext ctx) {
        for (int i = 0; i< ctx.getChildCount(); i++) {
            if (ctx.getChild(i) instanceof LismaParser.Var_identContext) {
                String code = ctx.getChild(i).getText();
                table.add(new HMConst(code));
            }
        }
        return null;
    }

    @Override
    public Object visitEquation(@NotNull LismaParser.EquationContext ctx) {
        VariableVisitor vv = new VariableVisitor();
        table.add(vv.visit(ctx.getChild(0)));
        return super.visitEquation(ctx);
    }

    @Override
    public Object visitState(@NotNull LismaParser.StateContext ctx) {
        // меняем таблицу переменных на ту что в состоянии
        HMState st = automata.getState( ctx.getChild(1).getText());
        VariableTableAggregatorVisitor aggregatorVisitor = new VariableTableAggregatorVisitor(st.getVariables(), automata);
        aggregatorVisitor.visit(ctx.getChild(5));
        return null;
    }

    @Override
    public Object visitApproximated_var(@NotNull LismaParser.Approximated_varContext ctx) {
        String code = ctx.getChild(1).getText();
        double from = Double.valueOf(ctx.getChild(3).getText());
        double to = Double.valueOf(ctx.getChild(5).getText());

        HMUnnamedConst cfrom = new HMUnnamedConst(from);
        HMUnnamedConst cto = new HMUnnamedConst(to);

        table.add(cfrom);
        table.add(cto);

        HMApproximateVariable variable = new HMApproximateVariable();
        variable.setCode(code);
        variable.setValFrom(cfrom);
        variable.setValTo(cto);

        LismaParser.Approximated_var_tailContext tail = (LismaParser.Approximated_var_tailContext) ctx.getChild(7);
        String type = tail.getChild(0).getText();
        if (type.equals("apx")) {
            variable.setType(HMApproximateVariable.ApproximateType.BY_NUMBER_OF_PIECES);
        } else if (type.equals("step")) {
            variable.setType(HMApproximateVariable.ApproximateType.BY_STEP);
        }

        HMConst apxVal = new HMUnnamedConst(Double.valueOf(tail.getChild(1).getText()));
        variable.setApxVal(apxVal);

        table.add(variable);

        return null;
    }

    @Override
    public Object visitApproximated_var_tail(@NotNull LismaParser.Approximated_var_tailContext ctx) {
        return super.visitApproximated_var_tail(ctx);    //To change body of overridden methods use File | Settings | File Templates.
    }
}
